package net.zoneland.zrdp.common.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.Nullable;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

/**
 * Jackson工具操作类.
 * @author pbody
 */
public final class JacksonUtils {
    private static final Logger LOGGER = LoggerFactory.getLogger(JacksonUtils.class);

    /** jackson对象. **/
    private static final ObjectMapper MAPPER = new ObjectMapper()
        //序列化的时候序列对象的那些属性 null 展示 属性名:null
        // .setSerializationInclusion(JsonInclude.Include.ALWAYS)
        //null值不参与序列化
        .setSerializationInclusion(JsonInclude.Include.NON_NULL)
        //反序列化时,遇到未知属性会不会报错：true - 遇到没有的属性就报错 false - 没有的属性不会管，不会报错
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        //如果是空对象的时候,不抛异常
        .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)

        // 允许出现单引号
        .configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
        //修改序列化后日期格式
        .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
        //处理不同的时区偏移格式
        .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
        .registerModule(new JavaTimeModule());

    private JacksonUtils() {
    }

    public static ObjectMapper getObjectMapper() {
        return MAPPER;
    }
    /**
    * 对象转json字符串.
    * @author pbody
    * @param object 对象信息
    * @return java.lang.String
    * @exception JsonProcessingException 转换异常
    **/
    public static String toJsonString(final Object object) throws JsonProcessingException {
        return MAPPER.writeValueAsString(object);
    }

    /**
     * 对象转json字符串.
     * @param object 对象信息
     * @return java.lang.String
     */
    public static String toString(final Object object) {
        try {
            return MAPPER.writeValueAsString(object);
        } catch (final JsonProcessingException e) {
            LOGGER.error("json转换异常", e);
            return "";
        }
    }

    /**
     * string 转 JsonNode
     * （注JsonNode 获取节点的文本 asText() 和 toString()是有区别的
     * {
     *     "pro": "value",
     *     "data": {
     *         "key": "test"
     *     }
     * }
     * obj.get("data").asText() 返回一个空字符串。
     * obj.get("data").toString() 返回 "{"key":"test"}"。
     * ）
     * @param jsonString 传入字符串
     * @return JsonNode 对象
     * @throws JsonProcessingException 转换异常
     */
    public static JsonNode toJsonNode(final String jsonString) throws JsonProcessingException {
        return MAPPER.readTree(jsonString);
    }

    /**
     * InputStream 转 JsonNode
     * @param in 传入流
     * @return JsonNode 对象
     * @throws IOException 转换异常
     */
    public static JsonNode toJsonNode(final InputStream in) throws IOException {
        return MAPPER.readTree(in);
    }
    /**
    * json字符串转对象.
    * @author pbody
    * @param jsonString json字符串
    * @param clazz 对象类
    * @param <T> 对象类型
    * @return T
    * @exception JsonProcessingException 转换异常
    **/
    public static <T> T toObject(final String jsonString, final Class<T> clazz) throws JsonProcessingException {
        if (jsonString == null){
            return null;
        }
        return MAPPER.readValue(jsonString, clazz);
    }

    /**
    * json字符串转泛型抽象对象，如List<>、Map<>等等.
    * @author pbody
    * @param jsonString json字符串
    * @param type 集合类型
    * @param <T> 对象类型
    * @return T
    * @exception JsonProcessingException 转换异常
    **/
    @Nullable
    public static <T> T toTypeObject(final String jsonString, final TypeReference<T> type) throws JsonProcessingException {
        if (jsonString == null){
            return null;
        }
        return MAPPER.readValue(jsonString, type);
    }

    /**
     * Map转json字符串.
     * @author pbody
     * @param map map信息
     * @return java.lang.String
     * @exception JsonProcessingException 转换异常
     **/
    public static String mapToJson(final Map<String, Object> map) throws JsonProcessingException {
        return MAPPER.writeValueAsString(map);
    }
}
